import datetime
from django.shortcuts import redirect
from django.utils.deprecation import MiddlewareMixin
from django.conf import settings
from web import models


class Tracer():
    """
    请求一进来我这边直接封装了三个对象供接口或者前端使用，分别是当前用户，当前用户享受的最高级别的套餐以及当前用户能看到的项目(包括创建和参与)
    在注册接口我需要加一个激活邮箱功能，所以我在传递给消息队列的用户id还是用最初的request.user.id,因为注册的user为None
    """

    def __init__(self):
        # 当前用户
        self.user = None
        # 价格策略
        self.price_policy = None
        self.project = None


class AuthMiddleware(MiddlewareMixin):

    def process_request(self, request):
        """ 如果用户已登录，则request中赋值 """
        # print(request.path_info)
        # 请求进来就给request一个tracer
        request.tracer = Tracer()

        user_id = request.session.get('user_id', 0)
        user_object = models.UserInfo.objects.filter(id=user_id).first()
        request.tracer.user = user_object

        # 白名单：没有登录都可以访问的URL
        """
        1. 获取当用户访问的URL
        2. 检查URL是否在白名单中，如果在则可以继续向后访问，如果不在则进行判断是否已登录
        """
        # request.path和path_info是一个概念，/开头的本站url，记住，没有收尾的/,只有开头/
        # 像这样/login/，第二个/老子卡半天，我白名单加的/login/，要改为/login
        if request.path_info in settings.WHITE_REGEX_URL_LIST or '/user/active' in request.path_info:
            # 如果返回空，表示中间件通过
            return

        # 检查用户是否已登录，已登录继续往后走；未登录则返回登录页面。
        if not request.tracer.user:
            return redirect('login')

        # 登录成功之后，访问后台管理时：获取当前用户所拥有的额度

        """
        # 方式一：免费额度在交易记录中存储，用户注册通过后，就有免费额度,我们手动create创建的

        # 获取当前用户ID值最大（降序交易记录）状态必须是已支付的，不可能为空，要么是免费额度，要么是付费额度
        _object = models.Transaction.objects.filter(user=user_object, status=2).order_by('-id').first()
        # 如果用户压根没买过，就不存在过期，如果买过，就要判断是否过期
        # 如果是免费用户，我们不会给它塞end_datetime字段
        current_datetime = datetime.datetime.now()
        # 这里如果有end_datetime，才是付款的用户，如果没有就不判断是否过期
        if _object.end_datetime:
            # 如果小于就证明过期，就塞给这个用户对象免费额度，如果没有过期，就还是正常的塞给付费额度
            # 用了个跨表查询，如果过期就去查到免费用户的价格策略塞给它，没过期，就正常返回47行查出来的额度
            if _object.end_datetime < current_datetime:
                _object = models.Transaction.objects.filter(user=user_object, status=2,
                                                            price_policy__category=1).first()
        # 拿到价格策略，塞给request
        request.tracer.price_policy = _object.price_policy
        """

        # 方式二：免费的额度不放在数据库了，毕竟免费用户多,所以就只有两种情况
        # 要么你是付费用户，交易表就有数据，要么就没有买过，你交易表一条数据都没有
        # 获取当前用户ID值最大（最近交易记录）
        _object = models.Transaction.objects.filter(user=user_object, status=2).order_by('-id').first()

        if not _object:
            # 没有购买把免费用户该有的免费额度塞给你
            request.tracer.price_policy = models.PricePolicy.objects.filter(category=1, title="个人免费版").first()
        else:
            # 付费版，有记录，说明你出钱了或者出过钱了
            current_datetime = datetime.datetime.now()
            # 再看你是否过期，过期
            if _object.end_datetime and _object.end_datetime < current_datetime:
                request.tracer.price_policy = models.PricePolicy.objects.filter(category=1, title="个人免费版").first()
            # 没过期就正常拿额度塞给你
            else:
                request.tracer.price_policy = _object.price_policy

            ############TODO:以后在视图中拿用户或用户额度就是这么玩
            # request.tracer.user  ------------用户对象
            # request.tracer.price_policy ---------------当前用户对应额度

            def process_view(self, request, view, args, kwargs):

                # 判断URL是否是以manage开头，如果是则判断项目ID是否是我创建 or 参与
                if not request.path_info.startswith('/manage/'):
                    return

                project_id = kwargs.get('project_id')
                # 是否是我创建的
                project_object = models.Project.objects.filter(creator=request.tracer.user, id=project_id).first()
                if project_object:
                    # 是我创建的项目的话，我就让他通过
                    request.tracer.project = project_object
                    return

                # 是否是我参与的项目
                project_user_object = models.ProjectUser.objects.filter(user=request.tracer.user,
                                                                        project_id=project_id).first()
                if project_user_object:
                    # 是我参与的项目
                    request.tracer.project = project_user_object.project
                    return

                return redirect('project_list')

    def process_view(self, request, view, args, kwargs):

        # 判断URL是否是以manage开头，如果是则判断项目ID是否是我创建 or 参与
        if not request.path_info.startswith('/manage/'):
            return

        project_id = kwargs.get('project_id')
        # 是否是我创建的
        project_object = models.Project.objects.filter(creator=request.tracer.user, id=project_id).first()
        if project_object:
            # 是我创建的项目的话，我就让他通过（这也给封装到request.tracer中去，为了以后视图中使用方便）
            request.tracer.project = project_object
            return

        # 是否是我参与的项目
        project_user_object = models.ProjectUser.objects.filter(user=request.tracer.user, project_id=project_id).first()
        if project_user_object:
            # 是我参与的项目也通过
            request.tracer.project = project_user_object.project
            return

        return redirect('project_list')
